﻿using System;
using System.Security.Cryptography;
using System.Text;

namespace CollectionAssistant
{
    /// <summary>
    /// Provide a set of extention methods to operate on string.
    /// </summary>
    public static class TextExtentions
    {
        /// <summary>
        /// Gets a GUID which represents the MD5 hash value of current string, using <see cref="Encoding.Default"/> encoding. 
        /// </summary>
        /// <param name="str">The input string to compute the hash value for.</param>
        /// <returns>A GUID which represents the MD5 hash value.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="str"/> is null.</exception>
        public static Guid ComputeHash(this string str)
        {
            return ComputeHash(str, Encoding.Default);
        }

        /// <summary>
        /// Gets a GUID which represents the MD5 hash value of current string, using specified encoding. 
        /// </summary>
        /// <param name="str">The input string to compute the hash value for.</param>
        /// <param name="encoding">The specified encoding.</param>
        /// <returns>A GUID which represents the MD5 hash value.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="str"/> or <paramref name="encoding"/> is null.</exception>
        public static Guid ComputeHash(this string str, Encoding encoding)
        {
            if (str == null)
                throw new ArgumentNullException("str");

            if (encoding == null)
                throw new ArgumentNullException("encoding");

            return ComputeHash(encoding.GetBytes(str));
        }

        /// <summary>
        /// Gets a GUID which represents the MD5 hash value of current byte-array. 
        /// </summary>
        /// <param name="buffer">The input byte-array to compute the hash value for.</param>
        /// <returns>A GUID which represents the MD5 hash value.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
        public static Guid ComputeHash(this byte[] buffer)
        {
            return ComputeHash(buffer, 0, buffer.Length);
        }

        /// <summary>
        /// Gets a GUID which represents the MD5 hash value of current byte-array. 
        /// </summary>
        /// <param name="buffer">The input byte-array to compute the hash value for.</param>
        /// <param name="offset">The offset into the byte-array from which to begin using data.</param>
        /// <param name="count">The number of bytes in the array to use as data. </param>
        /// <returns>A GUID which represents the MD5 hash value.</returns>
        /// <exception cref="ArgumentException">
        /// <para><paramref name="count"/> is an invalid value.</para>
        /// <para>-- or --</para>
        /// <para><paramref name="buffer"/> length is invalid.</para>
        /// </exception>
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is less than zero.</exception>
        public static Guid ComputeHash(this byte[] buffer, int offset, int count)
        {
            if (buffer == null)
                throw new ArgumentNullException("buffer");

            using (MD5 md5 = MD5.Create())
                return new Guid(md5.ComputeHash(buffer, offset, count));
        }
    }
}
